package com.heatup.apt.api.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.heatup.apt.api.service.CourseSignService;
import com.heatup.apt.common.util.*;
import com.heatup.apt.model.course.CourseTime;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.heatup.apt.common.constants.CommonConstants;
import com.heatup.apt.common.dao.CoachSigninLogMapper;
import com.heatup.apt.common.dao.CourseCoachMapper;
import com.heatup.apt.common.dao.CourseInfoMapper;
import com.heatup.apt.common.dao.CourseScheduleMapper;
import com.heatup.apt.common.dao.CourseSignMapper;
import com.heatup.apt.common.dao.OrderDetailMapper;
import com.heatup.apt.common.dao.OrderInfoMapper;
import com.heatup.apt.common.dao.coach.CoachInfoMapper;
import com.heatup.apt.common.dao.user.UserInfoMapper;
import com.heatup.apt.model.api.ApiResultModel;
import com.heatup.apt.model.api.course.CourseCoachDetailResultModel;
import com.heatup.apt.model.coach.CoachInfo;
import com.heatup.apt.model.coach.CoachSigninLog;
import com.heatup.apt.model.course.CourseCoach;
import com.heatup.apt.model.course.CourseInfo;
import com.heatup.apt.model.course.CourseInfoModel;
import com.heatup.apt.model.course.CourseSchedule;
import com.heatup.apt.model.course.CourseSign;
import com.heatup.apt.model.order.OrderDetail;
import com.heatup.apt.model.order.OrderUserInfo;
import com.heatup.apt.model.user.UserInfo;

@Service
public class CourseSignServiceImpl implements CourseSignService {

    public static final Logger log = LoggerFactory.getLogger(CourseSignServiceImpl.class);
    public static final String USER_SIGNIN_URL_PRE = CommonPropertiesUtil.getString("user_signin_url").trim();

    @Autowired
    private CourseSignMapper courseSignMapper;
    @Autowired
    private CourseInfoMapper courseInfoMapper;
    @Autowired
    private CourseScheduleMapper courseScheduleMapper;

    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private OrderInfoMapper orderInfoMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private CoachInfoMapper coachInfoMapper;
    @Autowired
    private CourseCoachMapper courseCoachMapper;
    @Autowired
    private CoachSigninLogMapper coachSigninLogMapper;

    public List<Map<String, Object>> queryUserCourseInfo(Integer userId, Integer courseId, Integer isclose, Integer orderId) {
        List<Map<String, Object>> map = courseSignMapper.queryUserCourseInfo(userId, courseId, isclose, orderId);
        return map;
    }

    /**
     * 销课
     *
     * @param storeId   门店地址
     * @param closeTime 销课时间
     * @return
     */
    @Override
    public Integer closeCourse(Integer id, Integer storeId, Date closeTime, Date startTime) {
        return courseSignMapper.closeCourse(id, storeId, closeTime, startTime);
    }

    /**
     * 销课
     *
     * <P>Date : 2016年10月21日 </P>
     *
     * @param num       课程顺序
     * @param id        签到ID
     * @param courseId  课程ID
     * @param storeId   门店ID
     * @param startTime 开始时间
     * @param closeTime 关闭时间
     * @return
     * @see com.heatup.apt.management.service.order.OrderService#updateCancelCourse(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, Integer)
     */
    @Override
    public int updateCancelCourse(String num, String id, String courseId,
                                  String storeId, String orderId, String startTime, String closeTime, Integer userId) throws Exception {

        Map<Object, Object> map = new HashMap<>();
        CourseSign cs = courseSignMapper.selectById(Integer.parseInt(id));
        if (cs == null) {
            throw new RuntimeException("没有对应的签到课程");
        }
        Integer num2 = cs.getCourseNumber();
        map.put("num", num2);
        map.put("orderId", orderId);
        int sign_less_num = orderInfoMapper.queryCourseSignLessNum(map);//已经签到了几节课
        OrderDetail orderDetail = orderDetailMapper.queryOrderDetailByOrderId(Integer.valueOf(orderId));
        if (num2.intValue() - 1 == sign_less_num) {
//            CourseCoachExample example = new CourseCoachExample();
//            example.or().andCourseIdEqualTo(Integer.valueOf(courseId));
//            List<CourseCoach> course_coach_list = courseCoachMapper.selectByExample(example);
            CourseCoach courseCoachDB = new CourseCoach();
            courseCoachDB.setCourseId(Integer.valueOf(courseId));
            EntityWrapper<CourseCoach> courseCoachEntityWrapper = new EntityWrapper<>(courseCoachDB);

            List<CourseCoach> course_coach_list = courseCoachMapper.selectList(courseCoachEntityWrapper);
            if (SetUtil.isNotNull(course_coach_list)) {
                map.put("coachId", course_coach_list.get(0).getCoachId());
            }
            map.put("storeId", storeId);
            map.put("startTime", startTime);
            map.put("closeTime", closeTime);
            map.put("id", Integer.valueOf(id));
            int count = orderInfoMapper.updateCancelCourse(map);

            map.clear();
            map.put("orderId", orderId);

            CourseInfo courseInfo = courseInfoMapper.selectById(Integer.valueOf(courseId));
            if (null != courseInfo) {
                /*int cs_count = courseInfo.getPeriods();*/
                int cs_count = (orderDetail.getCourseCount() != 0 ? orderDetail.getCourseCount() : courseInfo.getPeriods());
                if (cs_count != 0 && StringUtil.isEquals(num2, cs_count)) {
                    map.put("updatedBy", userId);
                    orderInfoMapper.updateOrderInfoStatus(map);
                }
            }
            return count;
        } else {
            return -1;
        }
    }

    /**
     * 教练 课程详情
     *
     * @param courseId 课程ID
     * @param mobile   教练手机
     * @return 课程详情
     */
    @Override
    public Map<String, Object> chaxuCoachCourseInfoById(Integer courseId, String mobile) throws Exception {

        Map<String, Object> resultMap = new HashMap<>();
        CourseCoachDetailResultModel course = courseSignMapper.queryCoachCourseInfo(courseId, mobile);
        if (course != null) {
            //查看课程是否即将开始
//            Date startTime = course.getStartTime();
//            Date endTime = course.getEndTime();

            CourseTime courseTime = courseInfoMapper.queryCourseStartTimeByCourseId(courseId);
            Date startTime = courseTime.getCourseStartTime();
            if (course.getCourseType().equals("3")) {
                String[] campClassTime = courseTime.getCampClassTime().split(",");
                startTime = DateUtil.parseUtilDate(campClassTime[courseTime.getWeek() - 1], DateUtil.FMT_DATE_YYYYMMDDHHMM);
            }
            Date nowTime = new Date();
            if (startTime != null) {
                String url;
                //检查二维码是否不存在
                if (StringUtils.isBlank(course.getSignInQrcodeUrl())) {
                    //不存在 需要生成
                    url = USER_SIGNIN_URL_PRE.replace("${courseId}", course.getCourseId().toString());
                    log.info("跳转URL ----------------->>> " + url);
                    //转换短链接创建二维码并上传到OSS返回URL
                    url = QRCodeUtil.createSignInQRCode(url);
                    course.setHeadImg(url);//跳转链接
                    //更新到DB
                    CourseInfo courseInfo = new CourseInfo();
                    courseInfo.setId(course.getCourseId());
                    courseInfo.setSignInQrcodeUrl(url);
                    courseInfo.setVersion(course.getVersion());
                    courseInfoMapper.updateSelectiveById(courseInfo);//updateByPrimaryKeyAndVersionSelective(courseInfo);
                } else {
                    //存在 直接从DB取
                    url = course.getSignInQrcodeUrl();
                }
                if (course.getCourseType().equals("1")) {//团课
                    //课程开始前20分钟 || 课程结束300分钟(5小时)内
                    if (nowTime.after(DateUtils.addMinutes(startTime, -20)) && DateUtils.addMinutes(startTime, 400).after(nowTime)) {
                        course.setSignInQrcodeUrl(url);//设置签到url返回
                    } else {
                        course.setSignInQrcodeUrl("");//不显示二维码
                    }
                } else if (course.getCourseType().equals("3")) {//檬营
                    CourseSchedule courseSchedule = courseScheduleMapper.selectByCourseId(courseId);
                    if (courseSchedule != null && StringUtils.isNotBlank(courseSchedule.getWeekly())
                            && courseSchedule.getWeekly().equals("1")
                            && course.getCurrentCount() >= course.getMinCount()) {//檬营成营和开启签到才返回二维码
                        course.setSignInQrcodeUrl(url);//设置签到url返回
                    } else {
                        course.setSignInQrcodeUrl("");//不显示二维码
                    }
                    resultMap.put("dateNow", new Date());
                }
            }
            if (course.getCourseType().equals("1") && course.getLeftDays() >= 0) {
                resultMap.put("signInCount", courseSignMapper.queryCoachCourseSignInCount(courseId, 1, mobile));
            } else if (course.getCourseType().equals("3")) {
                if (course.getCourseNumber() != null) {
                    int courseNumber = course.getCourseNumber();
                    resultMap.put("signInCount", courseSignMapper.queryCoachCourseSignInCount(courseId, courseNumber, mobile));
                }
            }
        }

        resultMap.put("course", course);
        return resultMap;
    }

    /**
     * 用户签到
     *
     * @param courseId 课程ID
     * @param openId   用户openId
     * @return
     * @throws Exception
     */
    @Override
    public ApiResultModel courseCoachUserSign(Integer courseId, String openId) throws Exception {
        log.info("用户签到 API----->> courseId " + courseId + " openId " + openId);
        ApiResultModel apiResultModel = new ApiResultModel();
        Map<String, Object> resultMap = new HashMap<>();
        boolean result = false;
        if (courseId == null || StringUtils.isBlank(openId)) {
            apiResultModel.setMsg("用户课程ID或openId不正确!不可签到");
            log.info("用户课程ID或openId不正确!不可签到");
        } else {
            //查询课程详情
            CourseInfoModel courseInfo = courseInfoMapper.queryCourseByCourseId(courseId);
            UserInfo userInfo = userInfoMapper.selectByOpenid(openId);

            //查询用户是否已经购买当前订单
            boolean isBuyThisOrder = orderInfoMapper.queryOrderByUserIdAndCourseId(userInfo.getId(), courseId) > 0;
            if (!isBuyThisOrder) {
                apiResultModel.setMsg("当前用户并没有购买此订单!不可签到");
                log.info("当前用户" + userInfo.getId() + "nickname " + userInfo.getNickName() + "并没有购买此订单!不可签到");
            } else {

                CourseSign courseSign = new CourseSign();
                courseSign.setCourseId(courseId);
                CourseSchedule courseSchedule = courseScheduleMapper.selectByCourseId(courseId);
                if (courseSchedule.getWeek() != null && courseInfo.getCourseType().equals("3")) {//檬营需要添加签到课时时序
                    courseSign.setCourseNumber(courseSchedule.getWeek());
                } else {//团课只有1节需要签到
                    courseSign.setCourseNumber(1);
                }
                courseSign.setUserId(userInfo.getId());
                courseSign.setIsclose(CommonConstants.NO);
                CourseSign courseSignDB = courseSignMapper.selectByCourseSign(courseSign);
                log.info("courseSignDB " + courseInfo.toString());
                if (courseSignDB != null) {
                    //已经签到过,不再重复插入数据,直接返回成功
                    result = true;
                } else {
                    courseSign.setCreatedBy(userInfo.getId());
                    courseSign.setCreatedTime(new Date());
                    result = courseSignMapper.insertSelective(courseSign) > 0;
                    log.info("用户签到 ---> " + userInfo.getId() + userInfo.getNickName() + userInfo.getMobile() + " 课程ID-> " + courseId + "result " + result);
                }
            }
        }

        resultMap.put("success", result);
        apiResultModel.setData(resultMap);
        return apiResultModel;
    }

    /**
     * 用户签到详情
     *
     * @param courseId 课程ID
     * @param userId   用户Id
     * @return
     * @throws Exception
     */
    @Override
    public ApiResultModel courseUserSignInfo(Integer courseId, Integer userId) throws Exception {
        log.info("用户签到 API----->> courseId " + courseId + " userId " + userId);
        ApiResultModel apiResultModel = new ApiResultModel();
        Map<String, Object> resultMap = new HashMap<>();
        boolean result = false;
        if (courseId == null || userId == null) {
            apiResultModel.setMsg("用户课程ID或userId不正确!不可签到");
            log.info("用户课程ID或userId不正确!不可签到");
        } else {
            //查询课程详情
            CourseInfoModel courseInfoDB = courseInfoMapper.queryCourseByCourseId(courseId);
            log.info("courseInfoDB " + courseInfoDB.toString());
            CourseInfoModel courseInfo = new CourseInfoModel();
            courseInfo.setId(courseInfoDB.getId());
            courseInfo.setCourseType(courseInfoDB.getCourseType());
            courseInfo.setTitle(courseInfoDB.getTitle());
            courseInfo.setCurrentCount(courseInfoDB.getCurrentCount());
            if (courseInfoDB.getStartTime() != null) {
                courseInfo.setStartTimeStr(com.heatup.apt.common.util.DateUtils.format(courseInfoDB.getStartTime(), com.heatup.apt.common.util.DateUtils.datePattern));
            }
            courseInfo.setHourMin(courseInfoDB.getHourMin());
            courseInfo.setIsVipUsed(courseInfoDB.getIsVipUsed());
            courseInfo.setStoreName(courseInfoDB.getStoreName());
            resultMap.put("course", courseInfo);

            UserInfo userInfoDB = userInfoMapper.selectById(userId);
            UserInfo userInfo = new UserInfo();
            userInfo.setId(userInfoDB.getId());
            userInfo.setHeadImg(userInfoDB.getHeadImg());
            userInfo.setNickName(userInfoDB.getNickName());
            userInfo.setLevel(userInfoDB.getLevel());
            resultMap.put("user", userInfo);

            //查询用户是否已经购买当前订单
            boolean isBuyThisOrder = false;
            //查询订单ID 人数 类型
            List<OrderUserInfo> orderUserInfoList = orderInfoMapper.queryOrderInfoByCourseIdAndUserId(userInfoDB.getId(), courseId);
            if (orderUserInfoList == null || orderUserInfoList.size() == 0) {
                apiResultModel.setMsg("当前用户并没有购买此订单!");
                log.info("当前用户" + userInfoDB.getId() + " nickname " + userInfoDB.getNickName() + "并没有购买此订单!");
            } else {
                isBuyThisOrder = true;
                resultMap.put("orderList", orderUserInfoList);
                result = true;
            }
            resultMap.put("isBuyThisOrder", isBuyThisOrder);
        }
        resultMap.put("success", result);
        apiResultModel.setData(resultMap);
        return apiResultModel;
    }

    /**
     * 教练 檬营开启/关闭签到
     *
     * @param courseId     课程ID
     * @param courseNumber 课时时序
     * @param type         签到类型 1开启 0关闭
     * @return
     */
    @Override
    public boolean campCourseSignIn(Integer courseId, Integer courseNumber, Integer userId, Integer type) throws Exception {
        if (courseId == null || courseNumber == null || type == null)
            return false;

        CourseSchedule campScheduleDB = courseScheduleMapper.selectByCourseId(courseId);
        if (courseNumber > campScheduleDB.getPeriods())
            throw new Exception("签到时序不可超过总课时");
        CourseSchedule campSchedule = new CourseSchedule();
        campSchedule.setId(campScheduleDB.getId());
        campSchedule.setWeek(courseNumber);
        campSchedule.setWeekly(type.toString());
        if (courseNumber.intValue() == campScheduleDB.getPeriods().intValue() && type == 0) {
            //教练签到最后一节课 并且是关闭签到时 将檬营课程变为已完成 不再更新闭营时间
//            campSchedule.setEndTime(new Date());
            CourseInfo courseInfo = courseInfoMapper.queryCourseInfoById(courseId);
            CourseInfo courseInfoDB = new CourseInfo();
            courseInfoDB.setId(courseInfo.getId());
            courseInfoDB.setStatus("5");
            courseInfoMapper.updateSelectiveById(courseInfoDB);
        }
        boolean result = courseScheduleMapper.updateSelectiveById(campSchedule) > 0;
        if (result) {
            //开启/关闭签到插入日志coach_signin_log
            CoachInfo coachInfo = coachInfoMapper.selectCoachInfoByCourseId(1, courseId);
            if (coachInfo != null) {

                CoachSigninLog coachSigninLog = new CoachSigninLog();
                coachSigninLog.setCoachId(coachInfo.getId());
                coachSigninLog.setCourseId(courseId);
                coachSigninLog.setCourseNumber(courseNumber);
                if (type == 1) {
                    //开启
                    coachSigninLog.setCourseSigninStartTime(new Date());
                    coachSigninLog.setCreatedBy(userId);
                    boolean suc = coachSigninLogMapper.insertSelective(coachSigninLog) > 0;
                    if (suc) {
                        log.info("教练开启檬营签到日志插入成功");
                    }
                }
                if (type == 0) {
                    //关闭签到
                    coachSigninLog = coachSigninLogMapper.selectOne(coachSigninLog);
                    coachSigninLog.setCourseSigninEndTime(new Date());
                    int courseSigninPersonCount = courseSignMapper.queryCoachCourseSignInCount(courseId,courseNumber, coachInfo.getMobile());
                    if (courseSigninPersonCount > 0) {
                        coachSigninLog.setCourseSigninPersonCount(courseSigninPersonCount);
                    }
                    boolean suc = coachSigninLogMapper.updateSelectiveById(coachSigninLog) > 0;
                    if (suc) {
                        log.info("教练关闭檬营签到日志插入成功");
                    }
                }
            }
        }
        return result;
    }
}